﻿using System.Collections.Generic;
using Jayden.Dll.Core.Membership;
using Jayden.Dll.Web.HtmlControls;
using Jayden.Dll.Web.Json;

namespace Jayden.Dll.Web.Controls.Admin
{
	public class UserRolesForm : Form
	{
		private Select m_Users;
		private Select m_RolesToRemove;
		private Select m_RolesToAdd;
		private Button m_AddRoles;
		private Button m_RemoveRoles;

		public override void Load(System.Xml.XmlNode node, HtmlControlLoader loader)
		{
			base.Load(node, loader);
			if (Id == null)
				Id = "userRolesForm";
			m_Users = GetFormElement<Select>("users");
			m_RolesToRemove = GetFormElement<Select>("rolesToRemove");
			m_RolesToAdd = GetFormElement<Select>("rolesToAdd");
			m_AddRoles = GetFormElement<Button>("addRoles", "command");
			m_RemoveRoles = GetFormElement<Button>("removeRoles", "command");
		}

		private void FillFromContext(HttpHandlerContext context)
		{

			UserDataAccess userDataAccess = context.UnitOfWork.DataAccessManager.GetDataAccess<UserDataAccess, User>();
			int totalRecords;
			List<User> users = userDataAccess.FindAll(0, int.MaxValue, out totalRecords);

			m_Users.Clear();
			m_RolesToAdd.Clear();
			m_RolesToRemove.Clear();

			m_Users.AddDefaultOption();
			foreach (User user in users)
				m_Users.AddOption(null, user.UserName);


			string queryUsers = context.Request["users"];
			User selectedUser = null;
			if (!string.IsNullOrWhiteSpace(queryUsers))
				selectedUser = userDataAccess.ReadByName(queryUsers);
			if (selectedUser != null)
			{
				m_Users.SelectedValue = selectedUser.UserName;
				RoleDataAccess roleDataAccess = context.UnitOfWork.DataAccessManager.GetDataAccess<RoleDataAccess, Role>();
				List<Role> roles = roleDataAccess.FindAll(0, int.MaxValue, out totalRecords);
				foreach (Role role in roles)
				{
					if (selectedUser.RoleNames.Contains(role.RoleName))
						m_RolesToRemove.AddOption(role.RoleName, role.RoleName);
					else
						m_RolesToAdd.AddOption(role.RoleName, role.RoleName);
				}
			}
			else
			{
				m_RolesToAdd.Disabled = true;
				m_RolesToRemove.Disabled = true;
				RoleDataAccess roleDataAccess = context.UnitOfWork.DataAccessManager.GetDataAccess<RoleDataAccess, Role>();
				List<Role> roles = roleDataAccess.FindAll(0, int.MaxValue, out totalRecords);
				foreach (Role role in roles)
					m_RolesToAdd.AddOption(role.RoleName, role.RoleName);
			}
			if (context.Json != null)
			{
				JsonObject toRemove = new JsonObject();
				JsonObject toAdd = new JsonObject();
				context.Json.Add(m_RolesToRemove.Id, toRemove);
				context.Json.Add(m_RolesToAdd.Id, toAdd);
				toRemove.Add("html", m_RolesToRemove.ToInnerHtml(context.Translator));
				toAdd.Add("html", m_RolesToAdd.ToInnerHtml(context.Translator));
				toRemove.Add("disabled", m_RolesToRemove.Disabled);
				toAdd.Add("disabled", m_RolesToAdd.Disabled);
			}
		}

		public override void ProcessHtmlRequest(HttpHandlerContext context)
		{
			RoleProviderDiv.RoleCommandHandler roleHandler = context.HandlerManager.GetHandler<RoleProviderDiv.RoleCommandHandler>();
			roleHandler.UsersAddedToRoles += new RoleProviderDiv.OnUsersAdddedToRoles(UsersAddedToRoles);
			roleHandler.UsersRemovedFromRoles += new RoleProviderDiv.OnUsersRemovedFromRoles(UsersRemovedFromRoles);
			FillFromContext(context);
			base.ProcessHtmlRequest(context);
		}

		public override void ProcessJsonRequest(HttpHandlerContext context)
		{
			RoleProviderDiv.RoleCommandHandler roleHandler = context.HandlerManager.GetHandler<RoleProviderDiv.RoleCommandHandler>();
			roleHandler.UsersAddedToRoles += new RoleProviderDiv.OnUsersAdddedToRoles(UsersAddedToRoles);
			roleHandler.UsersRemovedFromRoles += new RoleProviderDiv.OnUsersRemovedFromRoles(UsersRemovedFromRoles);
			FillFromContext(context);
			base.ProcessJsonRequest(context);
		}

		void UsersRemovedFromRoles(HttpHandlerContext context, string[] users, string[] roles)
		{
			if (users != null && users.Length == 1 && context.Request["users"] == users[0])
			{
				m_RolesToAdd.Clear();
				m_RolesToRemove.Clear();
				HashSet<string> removeRoles = new HashSet<string>(roles);
				UserDataAccess userDataAccess = context.UnitOfWork.DataAccessManager.GetDataAccess<UserDataAccess, User>();
				User selectedUser = userDataAccess.ReadByName(users[0]);
				RoleDataAccess roleDataAccess = context.UnitOfWork.DataAccessManager.GetDataAccess<RoleDataAccess, Role>();
				int totalRecords;
				List<Role> roleList = roleDataAccess.FindAll(0, int.MaxValue, out totalRecords);
				foreach (Role role in roleList)
				{
					if (selectedUser.RoleNames.Contains(role.RoleName) && !removeRoles.Contains(role.RoleName))
						m_RolesToRemove.AddOption(role.RoleName, role.RoleName);
					else
						m_RolesToAdd.AddOption(role.RoleName, role.RoleName);
				}
			}
			if (context.Json != null)
			{
				JsonObject toRemove = new JsonObject();
				JsonObject toAdd = new JsonObject();
				context.Json.Replace(m_RolesToRemove.Id, toRemove);
				context.Json.Replace(m_RolesToAdd.Id, toAdd);
				toRemove.Add("html", m_RolesToRemove.ToInnerHtml(context.Translator));
				toAdd.Add("html", m_RolesToAdd.ToInnerHtml(context.Translator));
			}
		}

		void UsersAddedToRoles(HttpHandlerContext context, string[] users, string[] roles)
		{
			if (users != null && users.Length == 1 && context.Request["users"] == users[0])
			{
				m_RolesToAdd.Clear();
				m_RolesToRemove.Clear();
				HashSet<string> addRoles = new HashSet<string>(roles);
				UserDataAccess userDataAccess = context.UnitOfWork.DataAccessManager.GetDataAccess<UserDataAccess, User>();
				User selectedUser = userDataAccess.ReadByName(users[0]);
				RoleDataAccess roleDataAccess = context.UnitOfWork.DataAccessManager.GetDataAccess<RoleDataAccess, Role>();
				int totalRecords;
				List<Role> roleList = roleDataAccess.FindAll(0, int.MaxValue, out totalRecords);
				foreach (Role role in roleList)
				{
					if (selectedUser.RoleNames.Contains(role.RoleName) || addRoles.Contains(role.RoleName))
						m_RolesToRemove.AddOption(role.RoleName, role.RoleName);
					else
						m_RolesToAdd.AddOption(role.RoleName, role.RoleName);
				}
			}
			if (context.Json != null)
			{
				JsonObject toRemove = new JsonObject();
				JsonObject toAdd = new JsonObject();
				context.Json.Replace(m_RolesToRemove.Id, toRemove);
				context.Json.Replace(m_RolesToAdd.Id, toAdd);
				toRemove.Add("html", m_RolesToRemove.ToInnerHtml(context.Translator));
				toAdd.Add("html", m_RolesToAdd.ToInnerHtml(context.Translator));
			}
		}

		public override void ProcessJsRequest(HttpHandlerContext context)
		{
			base.ProcessJsRequest(context);
			string id = GetType().FullName;
			context.Js[id].AppendOnInit(@"
	var $users = $('#" + m_Users.Id + @"');
	var $form = $('#" + Id + @"');
	var clicked = null;
	$('#" + Id + @" button').click(function() {
		clicked = this;
	});
	$users.change(function(e) {
		$form.submit();
	});
	$form.submit(function(e) {
		e.preventDefault();
		var command = clicked;
		clicked = null;
		return JAYDEN.sfn.submitAjax($form, command);
	});
");
			context.Js[id].AppendAjaxHtmlHandler(m_RolesToAdd, false, true);
			context.Js[id].AppendAjaxHtmlHandler(m_RolesToRemove, false, true);

		}
	}
}
